package com.qys.livesMall.finance.service.impl;


import com.qys.livesMall.common.constants.Constants;
import com.qys.livesMall.common.exception.QysException;
import com.qys.livesMall.common.message.MessageServer;
import com.qys.livesMall.finance.dao.FinanceShopAccountDao;
import com.qys.livesMall.finance.enums.AccountTradeTypeEnum;
import com.qys.livesMall.finance.enums.FinanceMessageEnum;
import com.qys.livesMall.finance.mapper.FinanceShopAccountMapper;
import com.qys.livesMall.finance.model.dto.AccountHandle;
import com.qys.livesMall.finance.model.dto.AccountSearch;
import com.qys.livesMall.finance.model.dto.shop.AddShopAccount;
import com.qys.livesMall.finance.model.entity.shop.FinanceShopAccount;
import com.qys.livesMall.finance.service.FinanceShopAccountDetailService;
import com.qys.livesMall.finance.service.FinanceShopAccountService;
import com.qys.livesMall.finance.service.FinanceShopEarnestMoneyAccountDetailService;
import com.qys.livesMall.finance.service.FinanceShopEarnestMoneyAccountService;
import com.qys.livesMall.framework.view.Paging;
import com.qys.livesMall.framework.view.QysPage;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import static com.qys.livesMall.finance.common.FinanceLockPrefix.SHOP_ACCOUNT_LOCK;

/**
 * <p>
 * 店铺余额表 服务实现类
 * </p>
 *
 * @author
 * @since 2023-06-06
 */
@Service("financeShopEarnestMoneyAccountService")
public class FinanceShopEarnestMoneyAccountServiceImpl extends AccountBaseServer implements FinanceShopEarnestMoneyAccountService {

    @Autowired
    private FinanceShopAccountDao shopAccountDao;

    @Autowired
    private FinanceShopAccountMapper shopAccountMapper;

    @Autowired
    private FinanceShopEarnestMoneyAccountDetailService shopEarnestMoneyAccountDetailService;

    @Autowired
    private MessageServer messageServer;


    @Override
    public FinanceShopAccount get(Long userId) {
        FinanceShopAccount balance=shopAccountDao.getByUserId(userId);
        return balance;
    }

    @Override
    public QysPage<FinanceShopAccount> list(AccountSearch search) {
        Paging<FinanceShopAccount> page=shopAccountMapper.search(new Paging<>(search));
        if (CollectionUtils.isEmpty(page.getRecords())){
            return QysPage.build(search);
        }
        return QysPage.to(page);
    }


    @Override
    public List<FinanceShopAccount> listByUserIds(List<Long> userIds) {
        return shopAccountDao.getByUserIds(userIds);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AccountHandle directIn(AccountHandle handle){
        boolean lock = getLock(SHOP_ACCOUNT_LOCK, handle.getShopId());
        try{
            if (lock) {
                BigDecimal inMoney = handle.getAmountIncurred().abs();
                FinanceShopAccount info = shopAccountDao.getByUserId(handle.getUserId());
                if (info == null) {
                    handle.setMessage(FinanceMessageEnum.SHOP_BALANCE_NOT_EXIST);
                    return handle;
                }
                if (info.getEarnestMoney()==null){
                    info.setEarnestMoney(BigDecimal.ZERO);
                }
                info.setEarnestMoney(info.getEarnestMoney().add(inMoney));
                handle.setTradeTypeEnum(AccountTradeTypeEnum.IN);
                //创建变更记录
                handle.setAmountIncurred(inMoney);
                shopEarnestMoneyAccountDetailService.add(handle,info);
                shopAccountDao.updateById(info);

                handle.setSuccess(true);
                return handle;
            }else {
                handle.setSuccess(false);
                handle.setMessage(FinanceMessageEnum.ACCOUNT_BUSY);
                return handle;
            }
        }catch (Exception e){
            throw new QysException(FinanceMessageEnum.ACCOUNT_ERROR);
        }finally {
            if (lock){
                releaseLock(SHOP_ACCOUNT_LOCK, handle.getShopId());
            }
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AccountHandle directOut(AccountHandle handle){
        boolean lock = getLock(SHOP_ACCOUNT_LOCK, handle.getShopId());
        try{
            if (lock) {
                BigDecimal outMoney = handle.getAmountIncurred().abs();
                FinanceShopAccount info = shopAccountDao.getByUserId(handle.getUserId());
                if (info == null) {
                    handle.setMessage(FinanceMessageEnum.SHOP_BALANCE_NOT_EXIST);
                    return handle;
                }
                if (info.getEarnestMoney()==null){
                    info.setEarnestMoney(BigDecimal.ZERO);
                }
                if (info.getEarnestMoney().compareTo(outMoney) == -1) {
                    handle.setMessage(FinanceMessageEnum.SHOP_BALANCE_BE_NOT_ENOUGH);
                    return handle;
                }
                info.setEarnestMoney(info.getEarnestMoney().subtract(outMoney));
                handle.setTradeTypeEnum(AccountTradeTypeEnum.OUT);
                //创建变更记录
                handle.setAmountIncurred(outMoney);
                shopEarnestMoneyAccountDetailService.add(handle,info);
                shopAccountDao.updateById(info);

                handle.setSuccess(true);
                return handle;
            }else {
                handle.setSuccess(false);
                handle.setMessage(FinanceMessageEnum.ACCOUNT_BUSY);
                return handle;
            }
        }catch (Exception e){
            throw new QysException(FinanceMessageEnum.ACCOUNT_ERROR);
        }finally {
            if (lock){
                releaseLock(SHOP_ACCOUNT_LOCK, handle.getShopId());
            }
        }
    }
}
